package com.itheima.bakery.demos.web.service;

import com.itheima.bakery.demos.web.Repositories.CartItemRepository;
import com.itheima.bakery.demos.web.Repositories.OrderDetailRepository;
import com.itheima.bakery.demos.web.Repositories.ProductRepository;
import com.itheima.bakery.demos.web.Repositories.UserRepository;
import com.itheima.bakery.demos.web.model.*;
import com.itheima.bakery.demos.web.service.impl.OrderServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import org.springframework.transaction.annotation.Transactional;

@Service
public class CartService {

    @Autowired
    private CartItemRepository cartItemRepository;

    @Autowired
    private ProductRepository productRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private OrderServiceImpl orderServiceImpl;
    @Autowired
    private OrderDetailRepository orderDetailRepository;

    private static final Logger logger = LoggerFactory.getLogger(CartService.class);

    @Transactional
    public CartItem addToCart(Integer userId, Integer productId, Integer quantity, HttpSession session) {
        // 确保用户存在
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new IllegalArgumentException("User with ID " + userId + " does not exist."));

        // 确保产品存在
        Product product = productRepository.findById(productId)
                .orElseThrow(() -> new RuntimeException("Product not found with ID: " + productId));

        // 查找购物车项，如果不存在则创建新的
        Optional<CartItem> cartItemOptional = cartItemRepository.findByUser_IdAndProduct_Id(userId, productId);
        CartItem cartItem = cartItemOptional.orElseGet(() -> {
            CartItem newCartItem = new CartItem();
            newCartItem.setUser(user);
            newCartItem.setProduct(product);
            return newCartItem;
        });

        // 更新购物车项的数量和子总计
        cartItem.setQuantity(cartItem.getQuantity() + quantity);
        BigDecimal price = product.getPrice();
        BigDecimal additionalSubtotal = price.multiply(new BigDecimal(quantity));
        cartItem.setSubtotal(cartItem.getSubtotal().add(additionalSubtotal));

        // 保存购物车项
        cartItem = cartItemRepository.save(cartItem);

        // 更新session中的购物车数据
        if (session != null) {
            List<CartItem> cart = (List<CartItem>) session.getAttribute("cart");
            if (cart == null) {
                cart = cartItemRepository.findByUser_Id(userId);
                session.setAttribute("cart", cart);
            } else {
                // 如果购物车已存在，则更新数量和子总计
                cart = cartItemRepository.findByUser_Id(userId);
                session.setAttribute("cart", cart);
            }
        }

        return cartItem;
    }
    // 计算购物车总金额
    @Transactional(readOnly = true)
    public BigDecimal calculateTotalAmount(Integer userId) {
        return cartItemRepository.sumSubtotalByUserId(userId);
    }

    // 清空购物车
    @Transactional
    public void clearCart(Integer userId, HttpSession session) {
        cartItemRepository.deleteByUserId(userId);
        if (session != null) {
            session.removeAttribute("cart");
        }
    }

    // 持久化购物车数据到数据库
    @Transactional
    public void persistCartInDatabase(HttpSession session) {
        if (session != null && session.getAttribute("cart") != null) {
            List<CartItem> cartItems = (List<CartItem>) session.getAttribute("cart");
            for (CartItem item : cartItems) {
                cartItemRepository.save(item);
            }
            session.removeAttribute("cart");
        }
    }


    public void setCartItemUserId(CartItem cartItem, Integer userId) {
        Optional<User> userOptional = userRepository.findById(userId);
        if (userOptional.isPresent()) {
            cartItem.setUser(userOptional.get());
        } else {
            throw new IllegalArgumentException("User with ID " + userId + " does not exist.");
        }
    }
    public List<CartItem> getCartItems(Integer userId, HttpSession session) {
        // 尝试从HttpSession中获取购物车数据
        List<CartItem> cartItemsFromSession = (List<CartItem>) session.getAttribute("cartItems");

        // 如果HttpSession中没有购物车数据，或者用户ID不匹配，则从数据库获取
        if (cartItemsFromSession == null || !cartItemsFromSession.stream().allMatch(item -> item.getUser().getUserID().equals(userId))) {
            cartItemsFromSession = cartItemRepository.findByUser_Id(userId) .stream()
                    .map(item -> {
                        if (item.getProduct() == null) {
                            item.setProduct(productRepository.findById(item.getProductId()).orElse(null));
                        }
                        return item;
                    })
                    .collect(Collectors.toList());
        }

        // 预加载Product信息，避免N+1查询问题
        cartItemsFromSession.forEach(item -> {
            if (item.getProduct() == null) {
                item.setProduct(productRepository.findById(item.getProductId()).orElse(null));
            }
        });

        return cartItemsFromSession;
    }

    // 检查购物车中是否存在指定的产品
    public boolean isProductInCart(Integer userId, Integer productId) {
        logger.info("Checking if product {} is in the cart for user {}", productId, userId);
        boolean exists = cartItemRepository.findByUser_IdAndProduct_Id(userId, productId).isPresent();
        logger.info("Product {} exists in cart for user {}: {}", productId, userId, exists);
        return exists;
    }
    @Transactional
    public Integer checkoutCart(Integer userId, HttpSession session) {
        // 获取购物车对象
        Cart cart = (Cart) session.getAttribute("cart");
        if (cart == null || cart.getItems().isEmpty()) {
            throw new IllegalArgumentException("购物车为空，无法结账");
        }

        // 创建订单
        Order order = new Order();
        order.setUserID(userId);
        order.setStatus("未支付"); // 假设初始状态为Pending
        BigDecimal totalAmount = BigDecimal.ZERO;

        // 为每个购物车项创建订单详情对象
        List<OrderDetail> orderDetails = new ArrayList<>();
        for (CartItem cartItem : cart.getItems()) {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setProduct(cartItem.getProduct());
            orderDetail.setQuantity(cartItem.getQuantity());
            orderDetail.setUnitPrice(cartItem.getProduct().getPrice());
            orderDetail.setSubtotal(cartItem.getSubtotal());
            orderDetails.add(orderDetail);
            totalAmount = totalAmount.add(cartItem.getSubtotal());
        }
        order.setTotalAmount(totalAmount);
        order.setDetails(orderDetails);

        // 保存订单和订单详情
        Order savedOrder = orderServiceImpl.saveOrder(order);
        for (OrderDetail orderDetail : orderDetails) {
            orderDetail.setOrder(savedOrder);
            orderDetailRepository.save(orderDetail);
        }

        // 清空购物车
        clearCart(userId, session);

        return savedOrder.getOrderID();
    }


    @Transactional
    public void updateCartItemQuantity(Integer userId, Integer productId, Integer quantityToAdd) {
        // 验证输入的数量
        if (quantityToAdd < 0) {
            throw new IllegalArgumentException("Quantity to add cannot be negative");
        }

        // 查找购物车项
        Optional<CartItem> cartItemOptional = cartItemRepository.findByUser_IdAndProduct_Id(userId, productId);

        // 由于已经确定购物车中存在该商品项，可以直接更新数量
        if (cartItemOptional.isPresent()) {
            CartItem cartItem = cartItemOptional.get();
            int newQuantity = cartItem.getQuantity() + quantityToAdd; // 将新的数量加到原有的数量上
            cartItem.setQuantity(newQuantity); // 更新数量
            cartItemRepository.save(cartItem); // 保存更新
        } else {
            // 这里理论上不会执行，因为已经确定商品存在于购物车中
            throw new RuntimeException("CartItem not found for user " + userId + " and product " + productId);
        }
    }

}
